//
//  VideoControlCenterViewController.m
//  IPCamera
//
//  Created by 宣佚 on 15/6/5.
//  Copyright (c) 2015年 Andon Health Co,.Ltd. All rights reserved.
//

#import "VideoControlCenterViewController.h"
#import "VideoCCViewBL.h"
#import "FFMPEGClinet_Video.h"
#import "FFMPEGClinet_Audio.h"
#import "LinkViewController.h"
#import "globalConfiguration.h"

/**
 *视频质量
 *  -Low 低质
 *  -Mid 中质
 *  -High 高质
 */
typedef enum : NSUInteger {
    Low_Level = 100,
    Mid_Level = 101,
    High_Level = 102,
} Video_Level_Type;


/**
 *按钮状态
 *  -Open 打开
 *  -Close 关闭
 */
typedef enum : NSUInteger {
    But_State_Open = 1,
    But_State_Close = 0,
} But_State;

@interface VideoControlCenterViewController () <TUTKClientVideoDelegate,TUTKClientDelegate,TUTKClientAudioDelegate,TUTKClientSetAudioFormatDelegate>
{
    FFMPEGClinet_Video *ffClient;
    NSLock *videoLock;
    NSMutableArray *bufferArray;
}

@property (nonatomic, strong) IBOutlet UIImageView *VideoView;

@property (nonatomic, strong) IBOutlet UIButton *audioBut;
@property (nonatomic, strong) IBOutlet UIButton *lightBut;
@property (nonatomic, strong) IBOutlet UIButton *soundAlertBut;
@property (nonatomic, strong) IBOutlet UIButton *actionAlertBut;
@property (nonatomic, strong) IBOutlet UIButton *Low_VideoBut;
@property (nonatomic, strong) IBOutlet UIButton *Mid_VideoBut;
@property (nonatomic, strong) IBOutlet UIButton *High_VideoBut;
@property (nonatomic, weak) IBOutlet UILabel *videoTimeLabel;

@property (nonatomic, assign) Video_Level_Type videoLevel;

@end

@implementation VideoControlCenterViewController

#pragma mark - life cycle

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UILabel *titleLabel;
    switch (self.linkType) {
        case LINKTYPE_TUTK:
            titleLabel = [[BD_CustomNavigationBar sharedHandler] CustomNavigationTitle:[NSString stringWithFormat:@"TUTK:%@",self.DeviceID]];
            break;
        case LINKTYPE_GOOLINK:
            titleLabel = [[BD_CustomNavigationBar sharedHandler] CustomNavigationTitle:[NSString stringWithFormat:@"GooLink:%@",self.DeviceID]];
            break;
        default:
            titleLabel = [[BD_CustomNavigationBar sharedHandler] CustomNavigationTitle:@"unknown"];
            break;
    }
    self.navigationItem.titleView = titleLabel;
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    _tutkclient.vdelegate = self;
    _tutkclient.safdelegate = self;
    _tutkclient.adelegate = self;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
#ifdef _TEST_VIDEO_
        [_tutkclient startVideoQueue:_avIndex];
#endif
        
#ifdef _TEST_AUDIO_
        [_tutkclient startAudioQueue:_avIndex WithAudioFormat:self.audioFormat ];
#endif
    });
    _videoLevel = Low_Level;
}

-(void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    _Low_VideoBut.tag = But_State_Open;
    [_Low_VideoBut setSelected:YES];
    _Low_VideoBut.backgroundColor = [UIColor colorWithRed:0.894f green:0.533f blue:0.588f alpha:1.00f];
    _Mid_VideoBut.tag = But_State_Close;
    [_Mid_VideoBut setSelected:NO];
    _Mid_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
    _High_VideoBut.tag = But_State_Close;
    [_High_VideoBut setSelected:NO];
    _High_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
}

-(void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    
    [_tutkclient stopVideoQueue:_avIndex];
    [_tutkclient stopAudioQueue:_avIndex];
}

#pragma mark - UITableViewDelegate

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 || indexPath.section == 1) {
        return [VideoCCViewBL getSingleControlCellHeight];
    }
    else if (indexPath.section == 2) {
        CGFloat h = [VideoCCViewBL getVideoViewCellHeight];
        return h;
    }
    else {
        return 44;
    }
}

#pragma mark - TUTKClientDelegate
/**
 *  TUTK开始连接
 */
-(void)Tutk_StartConnection
{
}

/**
 *  TUTK连接成功
 */
-(void)Tutk_Connected_Success:(int)avIndex
{
}

/**
 *  TUTK连接失败
 *
 *  @param errorMessage 失败原因
 */
-(void)Tutk_Connected_Failure:(NSString *)errorMessage
{
}
/**
 *  TUTK断开连接
 */

    //TODO: Tutk_Video_DisConnected_Success中的_tutkclient.delegate = self;被注释后是否就可以不用这些TUTKClientDelegate的代理方法了
-(void)Tutk_DisConnected_Success
{
    dispatch_async(dispatch_get_main_queue(), ^{
        ffClient = nil;
        [MBProgressHUD hideHUD];
        [MBProgressHUD showInfo:@"TUTK断开成功"];
    });
}

#pragma mark - TUTKClientVideoDelegate
-(void)Tutk_Video_StartConnection
{
    NSLog(@"======Tutk_Video_StartConnection======");
}

-(void)Tutk_Video_Connected_Success
{
    NSLog(@"======Tutk_Video_Connected_Success======");
}

-(void)Tutk_Video_DisConnected_Failure
{
    NSLog(@"======Tutk_Video_DisConnected_Failure======");
}

-(void)Tutk_Video_DisConnected_Success
{
    NSLog(@"======Tutk_Video_DisConnected_Success======");
        //TODO: 下面这句能否去掉，直接使用LinkViewController中的Tutk_DisConnected_Success:
    
    _tutkclient.delegate = self;
    [_tutkclient stop];
}

-(void)tutk_onVideoData:(const void *)data andlength:(unsigned int)length andframeindex:(unsigned int)frameIndex
{
    if (ffClient == nil) {
        ffClient = [FFMPEGClinet_Video sharedInstance];
        [ffClient initVideoForNetH264Stream];
        
        bufferArray = [NSMutableArray arrayWithCapacity:25];
        videoLock = [[NSLock alloc] init];
        
        [NSThread detachNewThreadSelector:@selector(VideoDecoderAndPlayWith) toTarget:self withObject:nil];
    }
    
    NSData *bufData = [[NSData alloc] initWithBytes:data length:length] ;
    [videoLock lock];
    
    if([bufferArray count] < 50)
    {
        [bufferArray addObject:bufData];
    }
    [videoLock unlock];

}
-(void)VideoDecoderAndPlayWith{
    NSData * popData;
    BOOL needSleep= false;
    while (1) {
        
        [videoLock lock];
        if ([bufferArray count] > 5) {
            needSleep = false;
            popData = [bufferArray firstObject];
            [bufferArray removeObjectAtIndex:0];
        }else
        {
            needSleep = true;
        }
        
        [videoLock unlock];
        
        if(needSleep){
            usleep(1000);
            continue;
        }
        
        if(popData){
            UIImage * image=[ffClient decodeWithMediaPureData:(uint8_t *)[popData bytes] Size: [popData length]];
            
                //            [NSThread detachNewThreadSelector:@selector(displayImage:) toTarget:self withObject:image];
            dispatch_async(dispatch_get_main_queue(), ^(){
                [self updateView:image];
                
            });
            usleep(5000);
        }
    }
}
-(void)Tutk_Video_Connected_Failure:(NSString *)errorMessage ErrorType:(ENUM_TUTK_AVERROR_TYPE)ErrorType
{
    NSLog(@"Tutk_Video_Connected_Failure");
}

-(void)Tutk_Audio_StartConnection
{
    NSLog(@"Tutk_Audio_StartConnection");
}

-(void)Tutk_Audio_Connected_Success
{
    NSLog(@"Tutk_Audio_Connected_Success");
}

-(void)Tutk_Audio_DisConnected_Success
{
    NSLog(@"Tutk_Audio_DisConnected_Success");
}

-(void)Tutk_Audio_DisConnected_Failure
{
    NSLog(@"Tutk_Audio_DisConnected_Failure");
}

-(void)Tutk_Audio_Connected_Failure:(NSString *)errorMessage ErrorType:(ENUM_TUTK_AVERROR_TYPE)ErrorType
{
    NSLog(@"Tutk_Audio_Connected_Failure");
}
-(void)AudioAuxFunc{
    NSLog(@"进行相关初始化操作");
    NSData *bufData;
    BOOL isInitSuccessfully= NO;
    
    OSStatus err;
    
        //针对于AAC进行的处理
    if(self.audioFormat == AUDIO_FORMAT_AAC){
        while(1){
            [self.audioLock lock];
            if([self.audioBufferArray count] >= 1 ){
                
                bufData = [self.audioBufferArray firstObject];
                MyData myData = [self.affClient getMyData];
                err = AudioFileStreamParseBytes(myData.audioFileStream, [bufData length],[bufData bytes], 0);
                if (err ) {
                    NSLog(@"解析数据包错误");
                }
                [self.audioBufferArray removeObjectAtIndex:0];
                isInitSuccessfully = YES;
            }
            [self.audioLock unlock];
            
            if(isInitSuccessfully)
            {
                [self.tutkclient setStopAudioRecvThread];
                return;
            }
        }
    }

        //针对于PCM和G711A进行的处理
    while(1){
        [self.audioLock lock];
        if([self.audioBufferArray count] >= QUEUE_BUFFER_SIZE ){
            for(int i = 0 ; i < QUEUE_BUFFER_SIZE; i++){
                bufData = [self.audioBufferArray firstObject];
                [self.affClient ReadPCMAndPlay:(char*)[bufData bytes] BufSize:(int)[bufData length] BufIndex:i];
                [self.audioBufferArray removeObjectAtIndex:0];
            }
            isInitSuccessfully = YES;
        }
        [self.audioLock unlock];
        
        if(isInitSuccessfully)
        {
            [self.tutkclient setStopAudioRecvThread];
            break;
        }
    }
}
-(void)tutk_onAudioData:(const void *)data andlength:(unsigned int)length
{
//    NSLog(@"Receive audio data");
    if (self.affClient == nil) {
        self.affClient = [FFMPEGClinet_Audio sharedInstance];

        
        self.audioBufferArray = [NSMutableArray arrayWithCapacity:50];
        self.audioLock = [[NSLock alloc] init];
        
        [self.affClient initFFmpegAudioStreamWithFormat:(ENUM_AUDIO_FORMAT)self.audioFormat ViewController:self];
        
        [NSThread detachNewThreadSelector:@selector(AudioAuxFunc) toTarget:self withObject:nil];
    }
    
    NSData *bufData = [[NSData alloc] initWithBytes:data+PADDINGBITS length:length-PADDINGBITS] ;
    
    [self.audioLock lock];
    if([self.audioBufferArray count] < 3)
    {
        [self.audioBufferArray addObject:bufData];
    }
    [self.audioLock unlock];
}

-(void)Tutk_SetAudioFormat_Failure
{
    NSLog(@"Tutk_SetAudioFormat_Failure");
    [_tutkclient stop];
}

-(void)Tutk_SetAudioFormat_Success
{
    NSLog(@"Tutk_SetAudioFormat_Success");
}

#pragma mark - event response

-(IBAction)audioButPress:(id)sender
{
    if (_audioBut.tag == But_State_Close) {
        _audioBut.tag = But_State_Open;
        [_audioBut setSelected:But_State_Open];
        _audioBut.backgroundColor = [UIColor colorWithRed:0.553f green:0.714f blue:0.847f alpha:1.00f];
    }
    else {
        _audioBut.tag = But_State_Close;
        [_audioBut setSelected:But_State_Close];
        _audioBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        [_tutkclient stopAudioQueue:_avIndex];
    }
}

-(IBAction)lightButPress:(id)sender
{
    if (_lightBut.tag == But_State_Close) {
        _lightBut.tag = But_State_Open;
        [_lightBut setSelected:But_State_Open];
        _lightBut.backgroundColor = [UIColor colorWithRed:0.553f green:0.714f blue:0.847f alpha:1.00f];
    }
    else {
        _lightBut.tag = But_State_Close;
        [_lightBut setSelected:But_State_Close];
        _lightBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
    }
}

-(IBAction)soundAlertButPress:(id)sender
{
    if (_soundAlertBut.tag == But_State_Close) {
        _soundAlertBut.tag = But_State_Open;
        [_soundAlertBut setSelected:But_State_Open];
        _soundAlertBut.backgroundColor = [UIColor colorWithRed:0.553f green:0.714f blue:0.847f alpha:1.00f];
    }
    else {
        _soundAlertBut.tag = But_State_Close;
        [_soundAlertBut setSelected:But_State_Close];
        _soundAlertBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
    }
}

-(IBAction)ActionAlertButPress:(id)sender
{
    if (_actionAlertBut.tag == But_State_Close) {
        _actionAlertBut.tag = But_State_Open;
        [_actionAlertBut setSelected:But_State_Open];
        _actionAlertBut.backgroundColor = [UIColor colorWithRed:0.553f green:0.714f blue:0.847f alpha:1.00f];
    }
    else {
        _actionAlertBut.tag = But_State_Close;
        [_actionAlertBut setSelected:But_State_Close];
        _actionAlertBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
    }
}

-(IBAction)Low_VideoButPress:(id)sender
{
    if (_videoLevel != Low_Level && _Low_VideoBut.tag == But_State_Close) {
        _videoLevel = Low_Level;
        _Low_VideoBut.tag = But_State_Open;
        [_Low_VideoBut setSelected:YES];
        _Low_VideoBut.backgroundColor = [UIColor colorWithRed:0.894f green:0.533f blue:0.588f alpha:1.00f];
        _Mid_VideoBut.tag = But_State_Close;
        [_Mid_VideoBut setSelected:NO];
        _Mid_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        _High_VideoBut.tag = But_State_Close;
        [_High_VideoBut setSelected:NO];
        _High_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
    }
}

-(IBAction)Mid_VideoButPress:(id)sender
{
    if (_videoLevel != Mid_Level && _Mid_VideoBut.tag == But_State_Close) {
        _videoLevel = Mid_Level;
        _Low_VideoBut.tag = But_State_Close;
        [_Low_VideoBut setSelected:NO];
        _Low_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        _Mid_VideoBut.tag = But_State_Open;
        [_Mid_VideoBut setSelected:YES];
        _Mid_VideoBut.backgroundColor = [UIColor colorWithRed:0.894f green:0.533f blue:0.588f alpha:1.00f];
        _High_VideoBut.tag = But_State_Close;
        [_High_VideoBut setSelected:NO];
        _High_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
    }
}

-(IBAction)High_VideoButPress:(id)sender
{
    if (_videoLevel != High_Level && _High_VideoBut.tag == But_State_Close) {
        _videoLevel = High_Level;
        _Low_VideoBut.tag = But_State_Close;
        [_Low_VideoBut setSelected:NO];
        _Low_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        _Mid_VideoBut.tag = But_State_Close;
        [_Mid_VideoBut setSelected:NO];
        _Mid_VideoBut.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        _High_VideoBut.tag = But_State_Open;
        [_High_VideoBut setSelected:YES];
        _High_VideoBut.backgroundColor = [UIColor colorWithRed:0.894f green:0.533f blue:0.588f alpha:1.00f];
    }
}

-(IBAction)back:(id)sender
{
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - private fun

    //更新视频显示
-(void)updateView:(UIImage *)image
{
    if(image){
        self.VideoView.image = image;
    }
}

#pragma mark - getter and setter

-(UIButton *)audioBut
{
    if (_audioBut == nil) {
        UIButton *but = [[UIButton alloc] init];
        but.tag = But_State_Close;
        _audioBut = but;
    }
    return _audioBut;
}

-(UIButton *)lightBut
{
    if (_lightBut == nil) {
        UIButton *but = [[UIButton alloc] init];
        but.tag = But_State_Close;
        _lightBut = but;
    }
    return _lightBut;
}

-(UIButton *)soundAlertBut
{
    if (_soundAlertBut == nil) {
        UIButton *but = [[UIButton alloc] init];
        but.tag = But_State_Close;
        _soundAlertBut = but;
    }
    return _soundAlertBut;
}

-(UIButton *)actionAlertBut
{
    if (_actionAlertBut == nil) {
        UIButton *but = [[UIButton alloc] init];
        but.tag = But_State_Close;
        _actionAlertBut = but;
    }
    return _actionAlertBut;
}

-(UIButton *)Low_VideoBut
{
    if (_Low_VideoBut == nil) {
        UIButton *but = [[UIButton alloc] init];
        if (_videoLevel == Low_Level) {
            but.tag = But_State_Open;
            [but setSelected:YES];
            but.backgroundColor = [UIColor colorWithRed:0.894f green:0.533f blue:0.588f alpha:1.00f];
        } else {
            but.tag = But_State_Close;
            [but setSelected:NO];
            but.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        }
        _Low_VideoBut = but;
    }
    return _Low_VideoBut;
}

-(UIButton *)Mid_VideoBut
{
    if (_Mid_VideoBut == nil) {
        UIButton *but = [[UIButton alloc] init];
        if (_videoLevel == Mid_Level) {
            but.tag = But_State_Open;
            [but setSelected:YES];
            but.backgroundColor = [UIColor colorWithRed:0.894f green:0.533f blue:0.588f alpha:1.00f];
        } else {
            but.tag = But_State_Close;
            [but setSelected:NO];
            but.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        }
        _Mid_VideoBut = but;
    }
    return _Mid_VideoBut;
}

-(UIButton *)High_VideoBut
{
    if (_High_VideoBut == nil) {
        UIButton *but = [[UIButton alloc] init];
        if (_videoLevel == High_Level) {
            but.tag = But_State_Open;
            [but setSelected:YES];
            but.backgroundColor = [UIColor colorWithRed:0.894f green:0.533f blue:0.588f alpha:1.00f];
        } else {
            but.tag = But_State_Close;
            [but setSelected:NO];
            but.backgroundColor = [UIColor colorWithRed:0.949f green:0.941f blue:0.933f alpha:1.00f];
        }
        _High_VideoBut = but;
    }
    return _High_VideoBut;
}

#pragma mark 解码方法

static int index_adjust[8] = {
    -1,-1,-1,-1,2,4,6,8};

static int step_table[89] = {
    7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,
    50,55,60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,
    408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,1552,1707,1878,2066,
    2272,2499,2749,3024,3327,3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,
    10442,11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767
};

- (void) adpcm_decode :( unsigned char * )raw len :(int) len decoded:( unsigned char *) decoded pre_sample:( int * )pre_sample index:( int * )index
{
    @try {
        int i;
        int code;
        int sb;
        int delta;
        short * pcm = (short *)decoded;
        len <<= 1;
        
        for (i = 0;i < len;i ++)
        {
            if (i & 0x01)
                code = raw[i >> 1] & 0x0f;
            else
                code = raw[i >> 1] >> 4;
            if ((code & 8) != 0)
                sb = 1;
            else
                sb = 0;
            code &= 7;
            
            delta = (step_table[* index] * code) / 4 + step_table[* index] / 8;
            if (sb)
                delta = -delta;
            * pre_sample += delta;
            if (* pre_sample > 32767)
                * pre_sample = 32767;
            else if (* pre_sample < -32768)
                * pre_sample = -32768;
            pcm[i] = * pre_sample;
            
            * index += index_adjust[code];
            if (* index < 0)
                * index = 0;
            if (* index > 88)
                * index = 88;
        }
        
    }
    @catch (NSException *exception) {
        //        [self exceptionOperator:exception];
    }
    @finally {
        
    }
}

@end
